package com.arthas.arthasforsba.utils;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author dingling
 * @desc 执行bat脚本工具
 * @date 2023-07-19 16:16
 **/

public class BashUtil implements InitializingBean {



    /**
     * 执行bat脚本文件，弹出cmd黑窗
     *
     * @param command      执行脚本文件命令
     * @param navigatePath 脚本文件所在文件夹地址
     */
    public static void runExecution(List<String> command, File navigatePath) {

        System.out.println(command);

        ProcessBuilder executeProcess = new ProcessBuilder(command);
        executeProcess.directory(navigatePath);
        try {
            Process resultExecution = executeProcess.start();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("执行异常");
        }
    }

    /**
     * 执行bat脚本，读取cmd输出内容
     * 注意：按行执行的，所以需要注意脚本编写的时候一条命令需要写进一行中，
     * 而且还要注意执行命令时所在的文件夹地址，如果是需要在特定文件夹下执行的命令，
     * 则需要每行命令开始时跳转到该目录
     *
     * @param batPath 执行的脚本文件绝对路径
     */
    public static Map<String, String> runExecution2(String batPath,List<String> param) {
        Map<String, String> map = new HashMap<>(5);
        try {
            return runExecution2(new FileInputStream(batPath),param);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return map;

    }


    public static Map<String, String> runExecution2(InputStream stream,List<String> param) {
        StringBuilder sb1 = new StringBuilder();
        StringBuilder sb2 = new StringBuilder();
        Map<String, String> map = new HashMap<>(5);
        try {
            //读取脚本
            BufferedReader br = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
            String line;
            List<String> batList = new ArrayList<>();
            while ((line = br.readLine()) != null) {
                if (!"".equals(line)) {

                    batList.add(line);
                }
            }
            for (String command : batList) {
                String[] cmd;
                command = addParam(command,param);
                if (SystemUtils.isWindows()) {
                    // windows
                    cmd = new String[]{"cmd", "/C", command};
                } else {
                    // linux
                    cmd = new String[]{"/bin/sh", "-c", command};
                }
                Process pro = Runtime.getRuntime().exec(cmd);
                boolean res = pro.waitFor(10L, TimeUnit.SECONDS);
                if(!res) {
                    map.put("msg","上传超时，稍后重试！");
                    return map;
                }
                BufferedReader br1 = new BufferedReader(new InputStreamReader(pro.getInputStream(), "GBK"));
                BufferedReader br2 = new BufferedReader(new InputStreamReader(pro.getErrorStream(), "GBK"));
                System.out.println("Input Stream:");
                while ((line = br1.readLine()) != null) {
                    System.out.println(line);
                    sb1.append(line).append(System.getProperty("line.separator"));
                }
                System.out.println("Error Stream:");
                while ((line = br2.readLine()) != null) {
                    System.out.println(line);
                    sb2.append(line).append(System.getProperty("line.separator"));
                }
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        } finally {
            map.put("getInputStreamString", sb1.toString());
            map.put("getErrorStreamString", sb2.toString());

        }
        return map;
    }

    private static String addParam(String command,List<String> param){
        String completeCommand = command;
        for (int i = 0; i < param.size(); i++) {
            if (!completeCommand.contains("$")){
                return completeCommand;
            }
            if (!completeCommand.contains("$"+(i+1))){
                continue;
            }
            completeCommand = completeCommand.replace("$"+(i+1),param.get(i));
        }
        return completeCommand;
    }


    public static void main(String[] args) {
        //cmd弹窗
//        File jsFile = new File("E:\\java\\arthas\\sba-arthas\\src\\main\\resources\\");
//
//        String cmdPrompt = "cmd";
//        String type = "/c";
//        String start = "start";
//        String bat = "uploadFile.bat";
//
//
//        List<String> updateCommand = new ArrayList<>();
//        updateCommand.add(cmdPrompt);
//        updateCommand.add(type);
//        updateCommand.add(start);
//        updateCommand.add(bat);
//
//        runExecution(updateCommand, jsFile);

        //不需要弹窗，获得命令执行后的输入流，打印执行结果
        List<String> param = new ArrayList<>();
//        param.add(staticFilePath);
        param.add("/data/work/file/arthas-file/");
        param.add("127.0.0.1");
        param.add("a.class");
        System.out.println(runExecution2("E:\\java\\arthas\\sba-arthas\\src\\main\\resources\\uploadFile.bat",param));
    }

    @Override
    public void afterPropertiesSet() throws Exception {

    }
}

